home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / Classes / HashFile / HashFile.m < prev    next >
Text File  |  1995-06-12  |  5KB  |  238 lines

  1. /* File: HashFile.m - db(3) to HashTable bridge
  2.  *
  3.  * By: Christopher Lane
  4.  * Symbolic Systems Resources Group
  5.  * Knowledge Systems Laboratory
  6.  * Stanford University
  7.  *
  8.  * Date: 10 September 1991
  9.  *
  10.  * Copyright: 1990, 1991 by The Leland Stanford Junior University.  This
  11.  * program may be distributed without restriction for non-commercial use.
  12.  */
  13.  
  14. #import <c.h>
  15. #import <libc.h>
  16. #import <string.h>
  17. #import <assert.h>
  18.  
  19. #import "HashFile.h"
  20.  
  21. #define OBJECT @encode(id)
  22.  
  23. #define NXRewind(stream) NXSeek(stream, 0L, NX_FROMSTART)
  24.  
  25. @implementation HashFile
  26.  
  27. + (BOOL) isHashFile:(const char *) name
  28. {
  29.     return dbExists((char *) name);
  30. }
  31.  
  32. - initFromFile:(const char *) name
  33. {
  34.     return [self initFromFile:name keyDesc:OBJECT valueDesc:OBJECT];
  35. }
  36.  
  37. - initFromFile:(const char *) name keyDesc:(const char *) aKeyDesc
  38. {
  39.     return [self initFromFile:name keyDesc:aKeyDesc valueDesc:OBJECT];
  40. }
  41.  
  42. - initFromFile:(const char *) name keyDesc:(const char *) aKeyDesc valueDesc:(const char *) aValueDesc
  43. {
  44.     NXTypedStream *typedStream;
  45.  
  46.     [self initKeyDesc:aKeyDesc valueDesc:aValueDesc];
  47.  
  48.     if((db = dbOpen(filename = (char *) name)) == NULL) {
  49.         [self free];
  50.         return nil;
  51.         }
  52.  
  53.     readOnly = (BOOL) ((db->flag & (dbFlagReadOnly | dbFlagCompressed)) != 0);
  54.  
  55.     assert(d.k.s = (char *) malloc((size_t) LEAFSIZE));
  56.     assert(d.c.s = (char *) malloc((size_t) LEAFSIZE));
  57.     
  58.     d.k.n = malloc_size(d.k.s);
  59.     d.c.n = malloc_size(d.c.s);
  60.  
  61.     assert(stream = NXOpenMemory(NULL, 0, NX_READWRITE));
  62.     assert(typedStream = NXOpenTypedStream(stream, NX_WRITEONLY));
  63.     offset = NXTell(stream);
  64.     NXCloseTypedStream(typedStream);
  65.     
  66.     return self;
  67. }
  68.  
  69. - free
  70. {    
  71.     free(d.k.s);
  72.     free(d.c.s);
  73.     NXCloseMemory(stream, NX_FREEBUFFER);
  74.     assert(dbClose(db));
  75.     
  76.     return [super free];
  77. }
  78.  
  79. - empty
  80. {    
  81.     if(!readOnly && dbClose(db) && dbCreate(filename) && (db = dbInit(filename)) != NULL) return [super empty];
  82.     
  83.     return nil;
  84. }
  85.  
  86. - (unsigned) count
  87. {
  88.     unsigned i = 0;
  89.  
  90.     if(dbFirst(db, &d) && d.k.n > 0) do { ++i; } while(dbNext(db, &d));
  91.     
  92.     assert(i >= count);
  93.     
  94.     return i;
  95. }
  96.  
  97. - (BOOL) isKey:(const void *) aKey
  98. {
  99.     if([super isKey:aKey]) return YES;
  100.  
  101.     [self _keyCvtIn:aKey];
  102.     
  103.     return((BOOL) dbFind(db, &d));
  104. }
  105.  
  106. - (void *) valueForKey:(const void *) aKey
  107. {
  108.     void *value = (void *) nil;
  109.     
  110.     if([super isKey:aKey]) return [super valueForKey:aKey];
  111.     
  112.     [self _keyCvtIn:aKey];
  113.  
  114.     if(dbFetch(db, &d)) [super insertKey:[self _keyCvtOut] value:(value = [self _valueCvtOut])];
  115.  
  116.     return value;
  117. }
  118.  
  119. - (void *) insertKey:(const void *) aKey value:(void *) aValue
  120. {
  121.     if(readOnly) return (void *) nil;
  122.     
  123.     [self _keyCvtIn:aKey];
  124.     [self _valueCvtIn:aValue];
  125.  
  126.     if(!dbStore(db, &d)) return (void *) nil;
  127.     
  128.     return [super insertKey:aKey value:aValue];
  129. }
  130.  
  131. - (void *) removeKey:(const void *) aKey;
  132. {
  133.     if(readOnly) return (void *) nil;
  134.  
  135.     [self _keyCvtIn:aKey];
  136.     if(!dbDelete(db, &d)) return (void *) nil;
  137.     
  138.     return([super removeKey:aKey]);
  139. }
  140.  
  141. - (NXHashState) initState
  142. {
  143.     NXHashState state = [super initState];
  144.  
  145.     if(state.i = dbFirst(db, &d)) {
  146.         state.i = d.k.n;
  147.         state.j = d.c.n;
  148.         }
  149.     
  150.     return state;
  151. }
  152.  
  153. - (BOOL) nextState:(NXHashState *) aState key:(const void **) aKey value:(void **) aValue
  154. {
  155.     if(aState->i == FALSE) return NO;
  156.         
  157.     d.k.n = aState->i;
  158.     d.c.n = aState->j;
  159.  
  160.     if(dbGet(db, &d)) {
  161.         *aKey = [self _keyCvtOut];
  162.         *aValue = [self _valueCvtOut];
  163.         }
  164.     else return NO;
  165.  
  166.     if(aState->i = dbNext(db, &d)) {
  167.         aState->i = d.k.n;
  168.         aState->j = d.c.n;
  169.         }
  170.  
  171.     return YES;
  172. }
  173.  
  174. - (void) _keyCvtIn:(const void *) aKey
  175. {
  176.     [self _datumCvtIn:&d.k from:aKey using:keyDesc];
  177. }
  178.  
  179. - (void) _valueCvtIn:(const void *) aValue
  180. {
  181.     [self _datumCvtIn:&d.c from:aValue using:valueDesc];
  182. }
  183.  
  184. - (void) _datumCvtIn:(Datum *) aDatum from:(const void *) aBuffer using:(const char *) aDesc
  185. {
  186.     NXTypedStream *typedStream;
  187.     
  188.     NXRewind(stream);
  189.     
  190.     assert(typedStream = NXOpenTypedStream(stream, NX_WRITEONLY));
  191.     
  192.     offset = NXTell(stream);
  193.  
  194.     NXWriteType(typedStream, aDesc, &aBuffer);
  195.     
  196.     aDatum->n = NXTell(stream) - offset;
  197.  
  198.     NXCloseTypedStream(typedStream);
  199.     
  200.     NXSeek(stream, offset, NX_FROMSTART);
  201.     
  202.     NXRead(stream, (void *) aDatum->s, aDatum->n);
  203. }
  204.  
  205. - (void *) _keyCvtOut
  206. {
  207.     return [self _datumCvtOut:&d.k using:keyDesc];
  208. }
  209.  
  210. - (void *) _valueCvtOut
  211. {
  212.     return [self _datumCvtOut:&d.c using:valueDesc];
  213. }
  214.  
  215. - (void *) _datumCvtOut:(Datum *) aDatum using:(const char *) aDesc
  216. {
  217.     NXTypedStream *typedStream;
  218.     void *buffer;
  219.     
  220.     assert(buffer = (void *) malloc((size_t) aDatum->n));
  221.     
  222.     NXSeek(stream, offset, NX_FROMSTART);
  223.     
  224.     NXWrite(stream, (void *) aDatum->s, aDatum->n);
  225.     
  226.     NXRewind(stream);
  227.  
  228.     assert(typedStream = NXOpenTypedStream(stream, NX_READONLY));
  229.  
  230.     NXReadType(typedStream, aDesc, &buffer);
  231.     
  232.     NXCloseTypedStream(typedStream);
  233.     
  234.     return buffer;
  235. }
  236.  
  237. @end
  238.